package cate.game.role.pvp.minecraft;

import cate.common.table.d.GDFunc;
import cate.common.table.pvp.minecraft.mine_area_base.MinecraftMineAreaBaseRow;
import cate.common.util.TimeTool;
import cate.game.play.proce.play.PlayPO;
import cate.game.play.vo.PlayReportVO;
import cate.game.play.vo.ReplayUtils;
import cate.game.res.MixRes;
import cate.game.role.Role;
import cate.game.role.farm.cache.AbstractCacheFarmFTC;
import cate.game.role.farm.island.po.HeroState;
import cate.game.role.pvp.minecraft.msg.MinecraftMineAreaFightResultResp;
import cate.game.role.pvp.minecraft.po.MinecraftGatherPO;
import cp.solution.manage.api.open.replay.ReplaySaveReq;
import cp.solution.manage.api.open.replay.ReplaySaveResp;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@NoteClass("矿洞争霸-采集区 战斗FTC")
public class MinecraftMineAreaFTC extends AbstractCacheFarmFTC<MinecraftGatherPO> {
    public static final byte FIGHT_TYPE_MONSTER = 0;
    public static final byte FIGHT_TYPE_PLAYER = 1;
    @NoteField("层数")
    public final int layer;
    @NoteField("配置ID")
    public final int tid;
    @NoteField("战斗类型 0打怪1打人")
    public final byte fightType;

    public MinecraftMineAreaFTC(Role role, int layer, int tid, byte fightType, byte posNum) {
        super(GDFunc.MINECRAFT_GATHER, role.getGame());
        setup(role);
        this.layer = layer;
        this.tid = tid;
        this.fightType = fightType;
        super.posNum = posNum;
    }

    @Override
    protected MinecraftGatherPO po(Role role) {
        return role.getPvp().minecraft.gatherPO;
    }

    @Override
    protected boolean hasNext(Role role, PlayPO playPO) {
        switch (fightType) {
            case FIGHT_TYPE_MONSTER: {
                MinecraftMineAreaBaseRow config = role.getGame().table.minecraft.mine_area_base.get(tid);
                if (config == null) {
                    return false;
                }
                return StringUtils.isNotBlank(config.getInsCode((byte) (posNum + 1)));
            }
            case FIGHT_TYPE_PLAYER: {
                return role.getPvp().minecraft.gatherPO.fightingPlaySides.size() >= (posNum + 1);
            }
            default:
                return false;
        }
    }

    @Override
    protected EcResult<Void> challengeNext(Role role, byte nextPos) {
        return role.getPvp().minecraft.gatherPO.challenge(nextPos);
    }

    @Override
    protected void handleBefore(Role role, PlayPO playPO) {
        try {
            ReplaySaveReq saveReq = ReplayUtils.toReplaySaveReq(playPO, System.currentTimeMillis() + TimeTool.TimeCons.WEEK);
            EcResult<ReplaySaveResp> r = role.getGame().openApi().saveReplay(saveReq);
            log.info("openApi之保存录像的结果是{}, ID {}", r, r.data.getId());
            if (r.ok()) {
                role.getPvp().minecraft.gatherPO.recordPlayUidToOpenId(playPO.uid, r.data.getId());
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    @Override
    protected void handleFinish(Role role, PlayPO playPO, boolean win, boolean next, List<PlayPO> caches) {
        switch (fightType) {
            case FIGHT_TYPE_MONSTER: {
                if (!next) {
                    // 上报战斗结果
                    MinecraftMineAreaFightResultResp resp = new MinecraftMineAreaFightResultResp();
                    resp.win = win;
                    resp.tid = tid;
                    resp.reward = new MixRes();
                    resp.reports = caches.stream().map(PlayReportVO::new).collect(Collectors.toList());
                    role.getGame().pvp.minecraft.getMessagingModule().fightResultReport(role,
                            layer,
                            tid,
                            win,
                            0,
                            0,
                            win ? role.getPvp().minecraft.gatherPO.buildSelfPlaySides() : null,
                            null,
                            resp);
                }
            }
                break;
            case FIGHT_TYPE_PLAYER: {
                // 结算血量
                playPO.teamEnd.b.getAllHero().forEach(ft -> {
                    boolean find = false;
                    for (HeroState state : role.getPvp().minecraft.gatherPO.resultHeroStates) {
                        if (state.heroUid.equals(ft.uid)) {
                            state.update(ft);
                            find = true;
                            break;
                        }
                    }
                    if (!find) {
                        HeroState state = new HeroState();
                        state.update(ft);
                        role.getPvp().minecraft.gatherPO.resultHeroStates.add(state);
                    }
                });
                role.getPvp().minecraft.gatherPO.resultHeroStates.removeIf(HeroState::isFull);
                if (!next) {
                    // 计算战力
                    long offensePower = 0;
                    long defensePower = 0;
                    List<PlayReportVO> reports = caches.stream().map(PlayReportVO::new).collect(Collectors.toList());
                    for (PlayReportVO report : reports) {
                        offensePower += report.a.getTotalPower();
                        defensePower += report.b.getTotalPower();
                    }
                    // 上报战斗结果
                    MinecraftMineAreaFightResultResp resp = new MinecraftMineAreaFightResultResp();
                    resp.win = win;
                    resp.tid = tid;
                    resp.reward = new MixRes();
                    resp.reports = reports;
                    role.getGame().pvp.minecraft.getMessagingModule().fightResultReport(role,
                            layer,
                            tid,
                            win,
                            offensePower,
                            defensePower,
                            win ? role.getPvp().minecraft.gatherPO.buildSelfPlaySides() : null,
                            win ? null : role.getPvp().minecraft.gatherPO.resultHeroStates,
                            resp);
                    if (win) {
                        role.getHistory().action.minecraftRobOther();
                    }
                }
            }
                break;
        }
        if (!next) {
            role.getPvp().minecraft.gatherPO.clearFightingInfos();
        }
    }
}
